package com.qingyun.edusysteam.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qingyun.edusysteam.dto.*;
import com.qingyun.edusysteam.entity.User;
import com.qingyun.edusysteam.mapper.UserMapper;
import com.qingyun.edusysteam.service.IUserService;
import com.qingyun.edusysteam.utils.RegexUtils;
import com.qingyun.edusysteam.utils.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.qingyun.edusysteam.utils.RedisConstants.*;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserHolder userHolder;
    @Override
    public Result userLogin(LoginFormDTO loginFormDTO, HttpSession session) {

        //校验登录码
        if(RegexUtils.isCodeInvalid(loginFormDTO.getCode())){
            return Result.fail("登陆码格式错误");
        }
        //校验账号格式
        if(RegexUtils.isAccountInvalid(loginFormDTO.getAccount())){
            return Result.fail("账号格式错误");
        }
        //校验密码格式
        if(RegexUtils.isPasswordInvalid(loginFormDTO.getPassword())){
            return Result.fail("密码格式错误");
        }

        //一致,根据账号号查询用户
        User user = baseMapper
                .selectOne(new LambdaQueryWrapper<User>()
                        .eq(User::getAccount, loginFormDTO.getAccount()));
        //判定用户是否存在
        if (user==null) {
            //用户不存在，
            return Result.fail("当前用户未入系统，请联系管理员");
        }
        //判定用户密码是否正确
        if(!user.getPassword().equals(loginFormDTO.getPassword())){
            return Result.fail("密码错误");
        }

        //获取数据库验证码
        String cacheCode=stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY);
        //获取发送过来的验证码
        String code=loginFormDTO.getCode();
        //判定验证码是否合法
        if (cacheCode == null || !cacheCode.equals(code)) {
            //不一致 报错
            return Result.fail("验证码错误");
        }

        //生成token
        String token= UUID.randomUUID().toString();
        //userDTO转map
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        Map<String, Object> map = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true) // 忽略null值字段（可选，根据业务需求）
                        .setFieldValueEditor((name, value) -> {
                            // 关键修复：null值处理
                            return value == null ? null : value.toString();
                        })
        );
        //保存用户信息到redis
        stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + token, map);
        //设置过期时间
        stringRedisTemplate.expire(LOGIN_USER_KEY + token, LOGIN_USER_TTL, TimeUnit.MINUTES);
        //生成用户登录成功后返回的信息
        LoginResponseDTO loginResponseDTO=new LoginResponseDTO();
        loginResponseDTO.setUserDTO(userDTO);
        loginResponseDTO.setToken(token);
        loginResponseDTO.setExpireTime(LOGIN_USER_TTL);
        return Result.ok(loginResponseDTO);
    }

    @Override
    public Result logout(String token) {
        String key=LOGIN_USER_KEY+token;
        if (BooleanUtil.isFalse(stringRedisTemplate.delete(key))){
            return Result.fail("退出失败，请联系管理员");
        }
        return Result.ok();
    }

    @Override
    public Result updatePassword(String token,UserPassWordDTO userPassWordDTO) {
        String oldPassWord=userPassWordDTO.getOldPassWord();
        String newPassWord=userPassWordDTO.getNewPassWord();
        Long teacherId = userHolder.getUserId();
        if (teacherId == null) {
            return Result.fail("用户未登录或Token失效");
        }

        User user = baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, teacherId));
        if(!user.getPassword().equals(oldPassWord)){
            return Result.fail("原密码输入错误");
        }
        if(RegexUtils.isPasswordInvalid(newPassWord)){
            return Result.fail("新密码格式错误,需满足4~32位");
        }
        user.setPassword(newPassWord);

        int success=baseMapper.update(user, new LambdaQueryWrapper<User>()
                .eq(User::getId, teacherId));
        if(success<=0){
            return Result.fail("修改密码失败");
        }
        return Result.ok();
    }
}